home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung (Tewi)(1994).iso
/
magazine
/
progjour
/
1989
/
03a
/
delim.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-04-19
|
6KB
|
320 lines
/*
* delim.c - a dbASE3 filter
*
* takes a text file with fields delimited with a 'delim' char
* and creates a file a comma delimited file with double quotes '"'
* around all fields so dBASE3 can import it
*
* Author: M. Steven Baker
* Last Revision: October 17, 1988
*/
/* Macros for constant definitions */
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#ifndef FILENAME_MAX
#define FILENAME_MAX 68
#endif
FILE *infp;
FILE *outfp = stdout; /* our file pointers */
char infile[FILENAME_MAX] = ""; /* our file names */
char outfile[FILENAME_MAX] = "";
int verbose = 0;
int noquote = 0;
int errflag = 0;
char delim = '\t'; /* default delimiter character */
char new_quote = ' '; /* default new quote character */
int fieldflag = 0; /* logical flag for field delimited cut */
int colflag = 0; /* logical flag fro column oriented cut */
int sflag = 0; /* the cut -s flag -- not implemented yet */
char *pgm = "delim"; /* our program name */
/*
main to open the files for scrub()
and handle invocation errors.
*/
void usage();
char *help_msg[] =
{
"DELIM takes an ascii text file with fields separated by a unique",
"delimiter character, and substitutes commas, and quotes for dBASE3.",
"The following options may be used singly or in combination:",
"-d delimiter \t field delimiter character (default = tab)",
"-o filename\t create output text file (default stdout)",
"-q char\t\t replace any double quotes with char (. stands for space)",
"\t\t so dBASE won't get confused",
"-v\t\t verbose mode"
};
main(argc,argv)
int argc;
char **argv;
{
int ch; /* variable for getopt */
extern int getopt();
extern char *optarg;
extern int optind, opterr;
/* process command-line arguments */
opterr = 0; /* first turn off error messages from getopt */
while ((ch = getopt(argc,argv, "vd:o:q:")) != EOF)
{
switch (ch) {
case 'd':
delim = *optarg;
break;
case 'v':
verbose = 1;
break;
case 'o': /* output specifed cut text file */
strcpy(outfile, optarg);
outfp = NULL;
break;
case 'q':
noquote = 1;
new_quote = *optarg;
if (new_quote == '.')
new_quote = ' ';
break;
default: /* unknown option */
errflag++;
break;
}
}
if (errflag || !(argc-optind) )
{
usage(pgm);
exit(1);
}
if ( convert(argc - optind, argv += optind) ) /* did we have errors? */
exit (1);
exit(0);
}
/*
* convert - process each filename or standard input
*/
int convert(ac, av)
int ac;
char **av;
{
int ch, errcount = 0;
char *p;
for (; ac > 0; --ac, ++av)
{
p = *av;
strcpy(infile,p); /* store input data filename */
if ((infp = fopen (infile,"rt")) == NULL)
{
fprintf(stderr,"%s: ERROR opening input file: %s\n",
pgm,infile);
continue;
}
if (outfp != stdout)
{
if ((outfp = fopen (outfile,"wt")) == NULL)
{
fprintf(stderr,"%s: ERROR opening output file: %s\n",outfile);
fclose (infp);
continue;
}
}
if (dodelim(infp,outfp)== EOF)
{
fprintf(stderr,"%s: Error converting file: %s\n",pgm,infile);
fclose(infp);
fclose(outfp);
errcount++;
continue;
}
fclose(infp);
if (fclose(outfp) == EOF)
{
fprintf(stderr,"%s: Error closing output file: %s\n",pgm,
outfile);
errcount++;
continue;
}
} /* end of for loop */
return (errcount);
}
#define BEGIN 0
#define INFIELD 1
#define DELIM 2
/*
procedure dodelim -- copy file to file replacing delimeters
*/
dodelim(fp1,fp2)
FILE *fp1; /* the input file pointer */
FILE *fp2; /* the output file pointer */
{
int c; /* 1 char buffer */
int i,state, last;
long count = 0; /* count of characters processed */
long linecnt = 0; /* number of lines processed */
long quotecnt = 0; /* count of quote characters replaced */
state = BEGIN;
while( (c = getc(fp1)) != EOF)
{
count++;
switch (state)
{
case BEGIN:
if (c == delim)
{
fputc('"',fp2); /* emit the first " */
fputc('"',fp2);
state = DELIM;
last = DELIM;
}
else
{
if (c == '\n')
{
fputc (c, fp2);
state = BEGIN;
linecnt++;
}
else /* got a starting CHAR */
{
fputc('"',fp2); /* emit the first " */
if (noquote)
{
if ( c == '"')
{
c = new_quote;
quotecnt++;
}
}
fputc (c, fp2);
state = INFIELD;
}
}
break;
case INFIELD:
if (c == delim)
{
fputc('"',fp2); /* emit the first " */
state = DELIM;
last = DELIM;
}
else
{
if (c == '\n')
{
fputc ('"',fp2);
fputc (c, fp2);
state = BEGIN;
linecnt++;
}
else /* got a CHAR */
{
if (noquote)
{
if ( c == '"')
{
c = new_quote;
quotecnt++;
}
}
fputc (c, fp2);
}
}
break;
case DELIM:
if (c == delim)
{
if (last == DELIM)
{
fputc(',',fp2);
fputc('"',fp2);
fputc('"',fp2);
}
else
{
fputc('"',fp2); /* then emit the first " */
state = DELIM;
last = DELIM;
}
}
else
{
if (c == '\n')
{
fputc (c, fp2);
state = BEGIN;
linecnt++;
}
else /* got a CHAR */
{
fputc (',',fp2);
fputc ('"',fp2);
if (noquote)
{
if ( c == '"')
{
c = new_quote;
quotecnt++;
}
}
fputc (c, fp2);
state = INFIELD;
}
}
break;
default:
return (EOF);
}
}
if (verbose)
{
printf("\n Characters processed: %ld Lines processed %ld\n",count,linecnt);
if (noquote && quotecnt > 0)
printf(" Quote characters replaced: %ld\n",quotecnt);
}
return (0);
}
/*
* usage - display an abbreviated help usage message
*/
void usage(pname)
char *pname;
{
int i, n = sizeof(help_msg)/sizeof (char *);
fprintf(stderr,"Usage: %s [options] file...\n\n",pname);
for (i = 0; i < n; ++i)
fprintf(stderr, "%s\n",help_msg[i]);
return;
}